package com.LachesismStorm.lachesism.service.impl;

import com.LachesismStorm.lachesism.core.exception.Asserts;
import com.LachesismStorm.lachesism.core.util.LachesismTools;
import com.LachesismStorm.lachesism.mapper.PubMapper;
import com.LachesismStorm.lachesism.service.PubService;
import com.LachesismStorm.lachesism.util.ImgUtil;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static com.LachesismStorm.lachesism.core.util.LachesismTools.getTime;

/**
 * 图片处理
 * 常用文件的文件头如下：(以前六位为准)
 * JPEG (jpg)，文件头：FFD8FF
 * PNG (png)，文件头：89504E
 * GIF (gif)，文件头：474946
 * TIFF (tif)，文件头：49492A
 *
 * @Author: lachesism
 * @Date: 2022/11/07/17:29
 * @Description:
 */
@Service
@Slf4j
public class PubServiceImpl implements PubService {

    private static final Map<String, String> supportMap = new HashMap<>();

    @Value("${file.image.address}")
    private String imageAddress;

    static {
        supportMap.put("FFD8FF", "jpg");
        supportMap.put("89504E", "png");
        supportMap.put("474946", "gif");
    }

    private static final String DOWNLOAD_PATH = "/Users/yuno/Downloads/x1/";
    private static final int MAX_RETRIES = 5;
    private static final int THREAD_POOL_SIZE = 5; // 线程池大小
    private final OkHttpClient client = new OkHttpClient();
    @Resource
    private PubMapper pubMapper;

    @Override
    public Map<String, String> uploadImg(MultipartFile multipartFile) {
        try {
            // 文件为空的场合
            if (multipartFile.isEmpty() || StringUtils.isEmpty(multipartFile.getOriginalFilename())) {
                Asserts.fail("图片不存在");
            }
            // 过滤文件类型为图片
            String fileType = getFileType(multipartFile.getBytes(), 6);
            if (!supportMap.containsKey(fileType)) {
                Asserts.fail("文件类型不支持!");
            }
            String orgFileName = multipartFile.getOriginalFilename();
            String fileExtend = orgFileName.substring(orgFileName.lastIndexOf(".") + 1);
            // UUID取得
            UUID uuid = UUID.randomUUID();
            String uuidStr = uuid.toString().substring(0, 6);
            uuidStr = uuidStr.replace("-", "");
            // 文件保存
            String newFileName = uuidStr + "." + fileExtend;
            //原始大小
            ImgUtil.changeScale(multipartFile.getInputStream(), 1, imageAddress + newFileName);
            Map<String, String> retMap = new HashMap<String, String>();
            retMap.put("oldName", orgFileName);
            retMap.put("newName", newFileName);
            return retMap;
        } catch (IOException e) {
            Asserts.fail("图片处理异常:" + e.getMessage());
            e.printStackTrace();
        }
        return null;
    }


    @Override
    public Map<String, String> uploadImage(MultipartFile file) throws Exception {
        if (file.isEmpty()) {
            Asserts.fail("文件为空");
        }
        // 获取原图
        BufferedImage originalImage = ImageIO.read(file.getInputStream());
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        String prefix = LachesismTools.getTime("yyyyMMddHHmmss");
        String fileExtension = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")); // Extract file extension
        // 判断原图大小是否超过300KB
        if (file.getSize() <= 300 * 1024) {
            // 原图大小不超过300KB，直接复制原图作为缩略图
            ImageIO.write(originalImage, "png", outputStream);
            uploadToDirectory(outputStream.toByteArray(), "/project/media/image/thumbnail/", "min_" + prefix + fileExtension);
//                uploadToDirectory(outputStream.toByteArray(), "/Users/yuno/Pictures/icon/icon2/minIcon2/", "min_" +prefix +  fileExtension);
            // 同时上传原图
            uploadToDirectory(file.getBytes(), "/project/media/image/original/", prefix + fileExtension);
//                uploadToDirectory(file.getBytes(), "/Users/yuno/Pictures/icon/icon2/", prefix + fileExtension);
        } else {
            // 原图大小超过300KB，进行缩放
            double scaleFactor = 300.0 / Math.max(originalImage.getWidth(), originalImage.getHeight());
            int scaledWidth = (int) (originalImage.getWidth() * scaleFactor);
            int scaledHeight = (int) (originalImage.getHeight() * scaleFactor);

            // 创建缩略图
            BufferedImage scaledImage = new BufferedImage(scaledWidth, scaledHeight, BufferedImage.TYPE_INT_RGB);
            Graphics2D g = scaledImage.createGraphics();
            g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
            g.dispose();
            // 将缩略图写入输出流
            ImageIO.write(scaledImage, "png", outputStream);
            uploadToDirectory(outputStream.toByteArray(), "/project/media/image/thumbnail/", "min_" + prefix + fileExtension);
//                uploadToDirectory(outputStream.toByteArray(), "/Users/yuno/Pictures/icon/icon2/minIcon2/", "min_" +prefix +  fileExtension);
            // 同时上传原图
            uploadToDirectory(file.getBytes(), "/project/media/image/original/", prefix + fileExtension);
//                uploadToDirectory(file.getBytes(), "/Users/yuno/Pictures/icon/icon2/", prefix + fileExtension);
        }
        Map<String, String> imgMap = new HashMap<String, String>();
        imgMap.put("oldName", "https://www.yunox.cn/original/" + prefix + fileExtension);
        imgMap.put("newName", "https://www.yunox.cn/thumbnail/" + "min_" + prefix + fileExtension);
        return imgMap;

    }

    @Override
    public String uploadFile(MultipartFile file) {

        return "www.yunox.cn/files/" + file.getName();
    }

    @SneakyThrows
    @Override
    public String uploadPic(MultipartFile file) {
        String orgFileName = file.getOriginalFilename();
        // 获取文件扩展名
        String fileExtend = orgFileName.substring(orgFileName.lastIndexOf(".") + 1).toLowerCase();

        // 生成唯一的文件名（防止文件名重复），统一保存为 PNG 格式
        String uniqueFileName = getTime("MMddHHmmSS") + ".png";

        // 指定保存路径
        String saveDir = imageAddress;
        // 创建文件目录（如果目录不存在，则创建）
        Path path = Paths.get(saveDir);
        if (!Files.exists(path)) {
            Files.createDirectories(path);  // 创建多级目录
        }
        // 创建目标文件路径
        File targetFile = new File(saveDir + uniqueFileName);
        // 首先尝试将文件转换成图片
        BufferedImage image = ImageIO.read(file.getInputStream());
        // 保存调整大小后的图片
        ImageIO.write(image, "PNG", targetFile);  // 使用 PNG 格式保存
        // 返回文件的绝对路径
        return targetFile.getAbsolutePath();
    }




    private void uploadToDirectory(byte[] data, String directoryPath, String fileName) throws IOException {
        File directory = new File(directoryPath);
        if (!directory.exists()) {
            directory.mkdirs();
        }
        FileOutputStream fos = new FileOutputStream(new File(directory, fileName));
        fos.write(data);
        fos.close();
    }


    private String getFileType(byte[] src, int magicNumberLength) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < magicNumberLength / 2; i++) {
            sb.append(Integer.toHexString(src[i] >> 4 & 0xF));
            sb.append(Integer.toHexString(src[i] & 0xF));
        }
        return sb.toString().toUpperCase();
    }


}
